package com.echo.boot.structure.map;

import java.util.Objects;

/**
 * Created with IntelliJ IDEA
 * Created By CQ
 * Date: 2020/6/12
 * Time: 21:31
 *
 * @author Administrator
 */
public class MyLinkedHashMap<K, V> extends MyHashMap<K, V> {
    private MyLinkedNode<K, V> first;
    private MyLinkedNode<K, V> last;

    private class MyLinkedNode<K, V> extends Node<K, V> {
        MyLinkedNode<K, V> prve;
        MyLinkedNode<K, V> next;

        public MyLinkedNode(K key, V value, Node<K, V> parent) {
            super(key, value, parent);
        }
    }

    @Override
    protected Node<K, V> createNode(K key, V value, Node<K, V> parent) {

        MyLinkedNode<K, V> node = new MyLinkedNode<>(key, value, parent);
        if (first == null) {
            first = last = node;
        } else {
            last.next = node;
            node.prve = last;
            last = node;
        }
        return node;

    }

    @Override
    public void clear() {
        super.clear();
        first = null;
        last = null;

    }

    @Override
    public void traversal(MapVisitor<K, V> visitor) {
        if (visitor == null) {
            return;
        }
        MyLinkedNode<K, V> node = first;
        while (node != null) {
            if (visitor.visit(node.key, node.value)) {
                return;
            }
            node = node.next;
        }
    }

    @Override
    protected void afterRemove(Node<K, V> wileNode, Node<K, V> removeNode) {
        MyLinkedNode<K, V> node1 = (MyLinkedNode<K, V>) wileNode;
        MyLinkedNode<K, V> node2 = (MyLinkedNode<K, V>) removeNode;
        // 删除度为2的节点的时候,交换要删除的节点 和 被代替的节点 链表的位置
        if (node1 != node2) {
            // 交换 prev
            MyLinkedNode<K, V> temp = node1.prve;
            node1.prve = node2.prve;
            node2.prve = temp;
            // 交换后
            if (node1.prve == null) {
                first = node1;
            } else {
                node1.prve.next = node1;
            }

            if (node2.prve == null) {
                first = node2;
            } else {
                node2.prve.next = node2;
            }

            // 交换 next;
            temp = node1.next;
            node1.next = node2.next;
            node2.next = temp;
            // 交换后
            if (node1.next == null) {
                last = node1;
            } else {
                node1.next.prve = node1;
            }

            if (node2.next == null) {
                last = node2;
            } else {
                node2.next.prve = node2;
            }

        }

        // 交换 两个元素 链表的位置


        MyLinkedNode<K, V> prve = node2.prve;
        MyLinkedNode<K, V> next = node2.next;
        if (prve == null) {
            first = node2;
        } else {
            prve.next = next.next;
        }

        if (next == null) {
            last = node2;
        } else {
            next.prve = node2.prve;
        }

    }

    @Override
    public boolean containsValue(V value) {
        MyLinkedNode<K, V> node = first;
        while (node != null) {
            if (Objects.equals(node.value, value)) {
                return true;
            }
        }
        return false;
    }
}
